package com.livestocksolutions;

import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import com.livestocksolutions.util.UpdateHistory;

/* -- Version History --
 *  1.0 : 10 July 2012 - Initial version.
 *  
 *  1.1 : 10 July 2012 - Changed weight from Float to double for greater precision.
 *  
 *  1.2 : 16 July 2012 - Class now implements Serializable
 */

/**
 * This class contains a date and weight for an animal
 * @author Adam Parr
 * @version 1.2
 * 
 * @.modified 16 July 2012
 */
public class Weight implements Serializable{
	/**
	 * Version number of class and value to determine un-serialised class compatibility
	 */
	private static final long serialVersionUID = 12L;
	
	/**
	 * Keep track of any changes, until this GroupHistory is assigned to an owner.
	 */
	protected HashMap<String,UpdateHistory> update = new HashMap<String,UpdateHistory>();
	/**
	 * The date that the weighting occurred
	 */
	private long date;
	/**
	 * The weight of the animal
	 */
	private double weight;
	
	/**
	 * Public constructor that creates a Weight
	 * @param date Date that the weighing occurred
	 * @param weight Weight of the animal at the given date given as a double
	 */
	public Weight(Date date, double weight){
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.set(Calendar.HOUR, 0);
		ca.set(Calendar.MINUTE, 0);
		ca.set(Calendar.SECOND, 0);
		ca.set(Calendar.MILLISECOND, 0);
		date=ca.getTime();
		this.date=date.getTime();
		this.weight=weight;
		
		update.put("DATE", new UpdateHistory(String.valueOf(this.date)));
		update.put("WEIGHT", new UpdateHistory(String.valueOf(this.weight)));
	}
	
	/**
	 * Get the date this weighing occurred
	 * @return date of the weighing stored in this Weight
	 */
	public Date getDate(){
		return date==0?null:new Date(date);
	}
	
	/**
	 * Get the ID of this Weighing, The date in long form of when this weighing occurred.
	 * @return long value representing the date this weighing occurred.
	 */
	public long getID(){
		return date;
	}
	
	/**
	 * Get the weight of the animal at stored in this Weight
	 * @return weight of the weighing stored in this Weight as a double
	 */
	public double getWeight(){
		return weight;
	}
	
	/**
	 * Updates this Object with the updated values from the different version.
	 * @param changes Weight that represents this Object in a different version.
	 * @return <tt>true</tt>.
	 */
	public boolean update(Weight changes){
		if(changes!=null && this!=changes){
			if(updateBefore("DATE",changes)){
				date=Long.parseLong(changes.update.get("DATE").getValue());
				update.put("DATE", new UpdateHistory(String.valueOf(date)));
			}
			
			if(updateBefore("WEIGHT",changes)){
				weight=Double.parseDouble(changes.update.get("WEIGHT").getValue());
				update.put("WEIGHT", new UpdateHistory(String.valueOf(weight)));
			}
			return true;
		}
		return false;
	}
	
	/**
	 * Checks to see if the modification date of the item at this position is before the changed value
	 * @param key The String key at which to compare the modification dates of the modified objects.
	 * @param changes The Weight that represents this Weight on another system.
	 * @return <tt>true</tt> if the old value was modified before the changed value. <tt>false</tt> otherwise.
	 */
	protected boolean updateBefore(String key,Weight changes){
		if(this.update.get(key)==null && changes.update.get(key)!=null){
			return true;
		}else if(changes.update.get(key)==null){
			return false;
		}
		return !this.update.get(key).getDate().after(changes.update.get(key).getDate());
	}
}
